
import React, {Component} from 'react';
import TRTCSocket from '../../../src/TRTCSocket';
import * as mediasoupClient from 'mediasoup-client';
import IdleTimerManager from 'react-native-idle-timer';

import {
  SafeAreaView,
  StyleSheet,
  ScrollView,
  View,
  Text,
  Button,
} from 'react-native';

import {
  RTCPeerConnection,
  RTCIceCandidate,
  RTCSessionDescription,
  RTCView,
  MediaStream,
  MediaStreamTrack,
  mediaDevices,
  registerGlobals,
} from 'react-native-webrtc';

const configuration = {iceServers: [{url: 'stun:stun.l.google.com:19302'}]};
const pc = new RTCPeerConnection(configuration);
let localStream;

function getLocalStream(isFront, callback) {
  mediaDevices.enumerateDevices().then((sourceInfos) => {
    console.log('sourceInfos====', sourceInfos);
    let videoSourceId;
    for (let i = 0; i < sourceInfos.length; i++) {
      const sourceInfo = sourceInfos[i];
      if (
        sourceInfo.kind === 'videoinput' &&
        sourceInfo.facing === (isFront ? 'front' : 'environment')
      ) {
        videoSourceId = sourceInfo.deviceId;
      }
    }
    console.log('videoSourceId=====11====', videoSourceId);
    mediaDevices
      .getUserMedia({
        audio: true,
        video: {
          mandatory: {
            minWidth: 640, // Provide your own width, height and frame rate here
            minHeight: 360,
            minFrameRate: 30,
          },
          facingMode: isFront ? 'user' : 'environment',
          deviceId: videoSourceId,
        },
      })
      .then((stream) => { 
        // Got stream!

        callback(stream);
      })
      .catch((error) => {
        // Log error
      });
  });
}
let roomId = 1609229906157;
let trtcSocket;
let that;
let device;
let streampull;
let onlineList = []; // 存放上线人的集合 然后依次拉流
let is_Pull = false; // 是否是拉流中
let track;
export default class home extends Component {
  //构造函数
  constructor(props) {
    super(props);
  }

  state = {
    connectState: false, // 是否连接成功
    joinRoomState: false, // 是否加入房间
    selfViewSrc: null,
    pullProducerMap: [],
    pullselfViewSrc: null,
    sendproducerTransportList: [],
    isFront: true, // 默认前置摄像头
  };

  componentDidMount() {
    that = this;
    console.log('1111111111');
    registerGlobals(); // 添加这一步才能获取到移动端的设备
    device = new mediasoupClient.Device();
    console.log('device==11===', device);
    console.log('mediasoupClient===1=', mediasoupClient.version);
    that._connectSocket();
  }
  componentWillMount() {
    console.log('componentWillMount=====');
    IdleTimerManager.setIdleTimerDisabled(true);
  }
  componentWillUnmount() {
    // IdleTimerManager.setIdleTimerDisabled(false);
  }
  render() {

    const {connectState, joinRoomState} = this.state;
    return (
      <View style={styles.container}>
        <View style={styles.viewrow}>
          <Text style={styles.textStys}>
            {connectState ? '连接成功' : '连接失败'}
          </Text>
          {/*<RTCView streamURL={this.state.selfViewSrc} style={styles.selfView} />*/}
          <Button title="退出房间" onPress={home._closeRoom} />
        </View>

        {!connectState ? (
          <Button title="重新连接socket" onPress={this._connectSocket} />
        ) : null}

        {/*<Button title="获取本地视频3" onPress={this._getLocalStream} />*/}
        {joinRoomState ? (
          this._joinRoomState_true()
        ) : (
          <Button title="加入房间" onPress={this._join} />
        )}
      </View>
    );
  }
  static _closeRoom() {
    console.log('推出房间');
    try {
      that.state.pullProducerMap.map((item, index) => {
        item.value.map((sub_item, sub_index) => {
          sub_item.transport.close();
        });
      });

      that.state.sendproducerTransportList.forEach((producerTransport) => {
        producerTransport.transport.close();
      });
      // trtcSocket.closeSocket();
    } finally {
      that.setState({
        pullProducerMap: [],
        joinRoomState: false,
      });
    }
  }
  // 关闭传输媒体
  _pushStream_coloes(producerTransport) {
    producerTransport.transport.close();
    // this.trtcRoom.closeTransport(producerTransport.transport.id);
    trtcSocket.sendMessage(
      {
        event: 'closeTransport',
        mediaData: {
          transportId: producerTransport.transport.id,
        },
      },
      (result, request) => {},
    );
    let arr = [];

    that.state.sendproducerTransportList.forEach((item) => {
      console.log('----------', item);
      if (item.producerId !== producerTransport.producerId) {
        arr.push(item);
      }
    });
    console.log('-------22222---', arr);
    that.setState({sendproducerTransportList: arr});
  }
  _switch_camera() {
    console.log(that.state.isFront);
    that.setState({isFront: !that.state.isFront}, () => {
      track._switchCamera();
    });
  }
  // 已加入房间
  _joinRoomState_true = () => {
    const {pullProducerMap, sendproducerTransportList, isFront} = this.state;
    return (
      <View>
        <View style={styles.viewrow}>
          <Button
            title="创建transport发送对象"
            onPress={this._createTransport}
          />
          <Button
            title={'切换' + (isFront ? '后置摄像' : '前置摄像')}
            onPress={this._switch_camera}
          />
        </View>

        {sendproducerTransportList.map((item, index) =>
          item.pushState ? (
            <Button
              title={'关闭流(' + item.produceType + ')' + item.producerId}
              onPress={() => {
                this._pushStream_coloes(item);
              }}
            />
          ) : (
            <View style={styles.viewrow}>
              <Button
                title="推视频"
                onPress={() => {
                  this._pushStream_video(item);
                }}
              />
              <Button
                title="推音频"
                onPress={() => {
                  this._pushStream_audio(item);
                }}
              />
            </View>
          ),
        )}

        <Button title="获取所有推流人" onPress={this._pullUserList} />
        <ScrollView style={{height: 300}}>
          {pullProducerMap.map((item, index) => (
            <View key={index}>
              <Text>姓名(sessionId:){item.key}</Text>
              <View style={styles.viewrow}>
                {item.value.map((sub_item, sub_index) => (
                  <Button
                    key={sub_index}
                    title={
                      sub_item.produceType == 'video'
                        ? '拉视频'
                        : sub_item.produceType == 'audio'
                        ? '拉音频'
                        : '未知流'
                    }
                    onPress={() => {
                      this._pullStream(sub_item);
                    }}
                  />
                ))}
              </View>
              <View style={styles.viewrow}>
                <RTCView
                  streamURL={item.pullselfViewSrc}
                  style={styles.selfView}
                />
                <Text>第{index}个</Text>
              </View>
            </View>
          ))}
        </ScrollView>
      </View>
    );
  };
  // 拉流  is_push  是否是推流上线自动拉流
  _pullStream(sub_item, is_push) {
    console.log('sessionId=========', sub_item.sessionId);
    console.log('producerId=========', sub_item.producerId);
    console.log('produceType=======', sub_item.produceType);

    // 创建Transport
    trtcSocket.sendMessage(
      {
        event: 'createTransport',
      },
      (result, request) => {
        console.log(result);
        console.log(request);
        // 是否失败
        if (result.event === 'ERROR') {
          console.log(
            `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
          );
          return;
        }
        const data = {
          id: result.mediaData.transportId,
          iceParameters: JSON.parse(result.mediaData.iceParameters),
          iceCandidates: JSON.parse(result.mediaData.iceCandidates),
          dtlsParameters: JSON.parse(result.mediaData.dtlsParameters),
        };
        let pullTransport = device.createRecvTransport(data);
        streampull = new MediaStream();
        pullTransport.on('connect', ({dtlsParameters}, callback, errback) => {
          console.log(
            '================================================================',
          );
          trtcSocket.sendMessage(
            {
              event: 'connectTransport',
              mediaData: {
                transportId: pullTransport.id,
                dtlsParameters: JSON.stringify(dtlsParameters),
              },
            },
            (result, request) => {
              console.log('connectTransport======', result);

              callback({});
            },
          );
        });
        // -------------------------------------------------------------------
        pullTransport.on('connectionstatechange', async (state) => {
          console.log(
            '---------------------------------------------------------------',
          );
          switch (state) {
            case 'connecting':
              break;

            case 'connected':
              // document.getElementById(pullProducer.producerId).srcObject = pullProducer.stream;
              that._pull_list_stream('connected');
              break;
            case 'failed':
              pullTransport.close();
              that._pull_list_stream('failed');
              break;

            default:
              break;
          }
        });

        that.consume(sub_item, is_push, pullTransport);
      },
    );
  }
  consume(sub_item, is_push, pullTransport) {
    //
    trtcSocket.sendMessage(
      {
        event: 'consume',
        mediaData: {
          producerId: sub_item.producerId,
          rtpCapabilities: JSON.stringify(device.rtpCapabilities),
        },
      },
      (result, request) => {
        console.log(result);
        console.log(request);
        // 是否失败
        if (result.event === 'ERROR') {
          console.log(
            `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
          );
          return;
        }
        const data = {
          producerId: result.parameterData.producerId,
          id: result.parameterData.consumerId,
          kind: result.mediaData.mediaKind,
          rtpParameters: JSON.parse(result.mediaData.rtpParameters),
          codecOptions: {},
        };

        pullTransport
          .consume(data)
          .then((consumer) => {
            console.log('这里执行了== pullTransport.consume======');
            streampull.addTrack(consumer.track);
            let arr = that.state.pullProducerMap;
            if (is_push) {
              let result = arr.some((item) => {
                if (item.key === sub_item.sessionId) {
                  return true;
                }
              });
              if (result) {
                arr.map((item, index) => {
                  if (sub_item.sessionId === item.key) {
                    item.value.push(sub_item);
                    if (consumer.track.kind === 'video') {
                      item.pullselfViewSrc = streampull.toURL();
                    }
                  }
                  return item;
                });
              } else {
                arr.push({
                  key: sub_item.sessionId,
                  value: [sub_item],
                  pullselfViewSrc: streampull.toURL(),
                });
              }
            } else {
              arr.map((item, index) => {
                if (
                  sub_item.sessionId === item.key &&
                  consumer.track.kind === 'video'
                ) {
                  item.pullselfViewSrc = streampull.toURL();
                }
                return item;
              });
            }

            let arr_a = arr.map((item, index) => {
              if (item.key === sub_item.sessionId) {
                let new_arr = [];
                item.value.map((sub, ind) => {
                  if (sub.producerId === sub_item.producerId) {
                    sub.transport = pullTransport;
                  }
                  new_arr.push(sub);
                });

                item.value = new_arr;
              }
              return item;
            });

            that.setState({pullProducerMap: arr_a});
          })
          .catch((err) => {
            console.log(err);
          });
      },
    );
  }
  // 获取所有推流人
  _pullUserList() {
    trtcSocket.sendMessage(
      {
        event: 'getRouterProducers',
      },
      (result, request) => {
        console.log(result);
        console.log(request);
        let list = result.parameterData.producerMap;
        let newList = [];
        Object.keys(list).forEach(function (key) {
          newList.push({key: key, value: list[key], pullselfViewSrc: null});
          console.log(key, list[key]);
        });
        console.log('newList=====', newList);
        that.setState({pullProducerMap: newList});
      },
    );
  }
  _getLocalStream() {
    getLocalStream(true, function (stream) {
      console.log('stream=====返回的====', stream);
      localStream = stream;
      that.setState({selfViewSrc: stream.toURL()});
    });
  }

  // 创建发送媒体对象
  _createTransport() {
    if (that.state.sendproducerTransportList.length > 1) return;
    console.log('device.canProduce=======', device.canProduce('video'));
    trtcSocket.sendMessage(
      {
        event: 'createTransport',
      },
      (result, request) => {
        console.log(result);
        console.log(request);
        // 是否失败
        if (result.event === 'ERROR') {
          console.log(
            `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
          );
          return;
        }

        const data = {
          id: result.mediaData.transportId,
          iceParameters: JSON.parse(result.mediaData.iceParameters),
          iceCandidates: JSON.parse(result.mediaData.iceCandidates),
          dtlsParameters: JSON.parse(result.mediaData.dtlsParameters),
          // sctpParameters: JSON.parse(result.mediaData.sctpParameters),
        };
        let producerTransport = device.createSendTransport(data);
        console.log('producerTransport=====', producerTransport);
        let arr = that.state.sendproducerTransportList;
        arr.push({
          transport: producerTransport,
          producerId: null,
          connectState: true,
          pushState: false,
        });
        that.setState({
          sendproducerTransportList: arr,
        });
      },
    );
  }
  _pushStream_video(producerTransport) {
    console.log('点击了推视频======');
    that._pushStream('video', producerTransport);
  }
  _pushStream_audio(producerTransport) {
    console.log('点击了推音频======');
    that._pushStream('audio', producerTransport);
  }
  async _pushStream(kind_type, producerTransport) {
    const $this = this;
    producerTransport.transport.on(
      'connect',
      async ({dtlsParameters}, callback, errback) => {
        console.log('call   connect.........');
        // eslint-disable-next-line max-len
        trtcSocket.sendMessage(
          {
            event: 'connectTransport',
            mediaData: {
              transportId: producerTransport.transport.id,
              dtlsParameters: JSON.stringify(dtlsParameters),
            },
          },
          (result, request) => {
            // 是否失败
            if (result.event === 'ERROR') {
              console.log(
                `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
              );
              return;
            }
            console.log('connectTransport======', result);

            callback({});
          },
        );
      },
    );

    producerTransport.transport.on(
      'produce',
      async ({kind, rtpParameters}, callback, errback) => {
        console.log('call   produce.........');
        try {
          // eslint-disable-next-line max-len
          trtcSocket.sendMessage(
            {
              event: 'produce',
              mediaData: {
                transportId: producerTransport.transport.id,
                mediaKind: kind,
                rtpParameters: JSON.stringify(rtpParameters),
                produceType: kind,
              },
            },
            (result, request) => {
              // 是否失败
              if (result.event === 'ERROR') {
                console.log(
                  `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
                );
                return;
              }
              console.log('result   produce.........');
              console.log(request);
              const id = result.mediaData.producerId;
              console.log('producerId=====', id);
              let arr = that.state.sendproducerTransportList.map((item) => {
                console.log('==1111111111===');
                if (item.transport === producerTransport.transport) {
                  item.pushState = true;
                  item.producerId = result.mediaData.producerId;
                  item.produceType = result.mediaData.produceType;
                  console.log('=22222222===');
                }
                return item;
              });
              console.log('=333333333===', arr);

              that.setState({
                sendproducerTransportList: arr,
              });
              callback({id});
            },
          );
        } catch (e) {
          errback(e);
        }
      },
    );

    producerTransport.transport.on('connectionstatechange', (state) => {
      console.log('call   connectionstatechange.........');
      console.log(state);
      switch (state) {
        case 'connecting':
          console.log(':connecting');
          break;

        case 'connected':
          console.log(':connected');
          break;

        case 'failed':
          console.log(':failed');
          producerTransport.transport.close();
          break;
        default:
          break;
      }
    });

    try {
      const stream = await that.getUserMedia(kind_type);

      let params = {};
      if (kind_type == 'video') {
        track = stream.getVideoTracks()[0];
        // 888888
        // const video = document.getElementById('video');
        // video.srcObject = stream;

        params.encodings = [
          {maxBitrate: 100000},
          {maxBitrate: 300000},
          {maxBitrate: 900000},
        ];
        params.codecOptions = {
          videoGoogleStartBitrate: 1000,
        };
      } else if (kind_type == 'audio') {
        track = stream.getAudioTracks()[0];
      }
      params.track = track;
      console.log('produce param:', params);
      that.setState({selfViewSrc: stream.toURL()});
      this.producer = await producerTransport.transport.produce(params);
    } catch (err) {
      console.log(err);
    }
  }
  async getUserMedia(kind) {
    console.log('getUserMedia===');
    if (!device.canProduce('video')) {
      console.log('cannot produce video');
      return;
    }

    try {
      // eslint-disable-next-line consistent-return
      return await mediaDevices.getUserMedia({
        audio: kind === 'audio',
        video:
          kind === 'video'
            ? {
                mandatory: {
                  minWidth: 640, // Provide your own width, height and frame rate here
                  minHeight: 360,
                  minFrameRate: 30,
                },
                facingMode: that.state.isFront ? 'user' : 'environment',
                // deviceId: videoSourceId,
              }
            : false,
      });
    } catch (err) {
      console.error('getUserMedia() failed:', err.message);
      throw err;
    }
  }
  // 连接Socket
  _connectSocket() {
    console.log('点击了连接socket======');
    trtcSocket = new TRTCSocket(
      'wss://trtc.idaka.vip:8888/trtc',
      this.producerOnline,
      this.producerOffline,
    );
    trtcSocket.is_Socket_state((result) => {
      console.log('====连接状态==', result);
      that.setState({connectState: result});
    });
  }
  _closeSocket() {
    trtcSocket.closeSocket();
  }

  // 拉流链接创建后执行的
  _pull_list_stream(type) {
    if (onlineList.length > 0) {
      let mediaData = onlineList[0];
      onlineList.splice(0, 1);
      that._pullStream(mediaData, true);
    } else {
      is_Pull = false;
    }
  }
  producerOnline(mediaData) {
    console.log('上线了=========', mediaData.producerId);
    if (is_Pull) {
      onlineList.push(mediaData);
    } else {
      is_Pull = true;
      that._pullStream(mediaData, true);
    }
  }
  producerOffline(mediaData) {
    console.log('下线了=========', mediaData.producerId);
    let arr = [];
    that.state.pullProducerMap.map((item, index) => {
      let arr_new = [];
      item.value.map((sub_item, sub_index) => {
        if (sub_item.producerId == mediaData.producerId) {
          if (sub_item.transport.kind == 'video') {
            sub_item.pullselfViewSrc = null;
          }
          sub_item.transport.close();
        } else {
          arr_new.push(sub_item);
        }
      });
      item.value = arr_new;

      if (item.value.length > 0) {
        arr.push(item);
      }
    });
    that.setState({
      pullProducerMap: arr,
    });
  }
  // 加入创建房间
  _join() {
    console.log('that.props.roomId======',that.props.roomId)
    trtcSocket.sendMessage(
      {
        event: 'getRouterRtpCapabilities',
        parameterData: {
          roomId: that.props.roomId,
        },
      },
      (result, request) => {
        console.log(result);
        console.log(request);
        // 是否失败
        if (result.event === 'ERROR') {
          console.log(
            `请求失败 CODE:${result.code}, MESSAGES: ${result.message}`,
          );
          return;
        }
        const rtpCapabilities = JSON.parse(result.mediaData.rtpCapabilities);
        // 设置媒体能力
        device.load({routerRtpCapabilities: rtpCapabilities});

        setTimeout(() => {
          that.setState({
            joinRoomState: true,
          });
        }, 1000);
        // 设置加入标识
      },
    );
  }
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  selfView: {
    width: 200,
    height: 150,
  },
  viewrow: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    padding: 10,
  },
  textStys: {
    fontSize: 36,
    marginTop: 10,
  },
});
